package com.teamwings.util;

import com.alibaba.druid.pool.DruidDataSource;
import com.teamwings.config.MybatisPlusConfig;
import com.teamwings.config.druid.vo.DataSourceVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class DBUtil {

	private final static Logger logger = LoggerFactory.getLogger(DBUtil.class);

	private static DataSourceVO vo;

	private static String SCHEMA;

	/**
	 * 在初始化单位数据库后，获取租户表
	 * @param dataSource 数据源
	 */
	public static void initTenantTables(DruidDataSource dataSource) {
		List<String> rs = new ArrayList<>();
		Connection connection = null;
		ResultSet resultSet = null;
		try {
			String sql = "SELECT TABLE_NAME FROM SYS_TENANT_TABLES;";
			connection = dataSource.getConnection().getConnection();
			resultSet = connection.prepareStatement(sql).executeQuery();
			while (resultSet.next()) {
				rs.add(resultSet.getString("TABLE_NAME").toLowerCase());
			}
		} catch (SQLException e) {
			logger.error("获取租户表异常");
		} finally {
			try {
				if (connection != null) {
					connection.close();
				}
				if (resultSet != null) {
					resultSet.close();
				}
			} catch (SQLException e) {
				logger.error("连接关闭异常");
			}
		}
		MybatisPlusConfig.setTenantTable(rs);
	}


	/**
	 * 获取模式
	 * @return
	 */
	public static String getSchema() {
		return SCHEMA;
	}

	/**
	 * 获取模式前缀
	 * @return
	 */
	public static String getSchemaPrefix() {
		return "\"" + SCHEMA + "\".";
	}

	/**
	 * 获取单位库信息
	 * 目前作用于online表单建表方言
	 * @return
	 */
	public static DataSourceVO getDataSource() {
		return vo;
	}

	/**
	 * 连接公共库获取单位库连接
	 * @param unitId
	 * @param url
	 * @param username
	 * @param password
	 * @return
	 */
	public static DataSourceVO getUnitDataBase(String unitId, String url, String username, String password) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		vo = new DataSourceVO();
		try {
			// 此处为人大金仓数据库
			String sql = "SELECT * FROM OAT_UNIT_LIST WHERE UNIT_ID = " + unitId;
			DriverManager.registerDriver(new com.kingbase8.Driver());
			conn = DriverManager.getConnection(url, username, password);
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			while (rs.next()) {
				String dbType = rs.getString("DB_TYPE");
				String dbName = rs.getString("DB_NAME");
				String dbSchema = rs.getString("DB_SCHEMA");
				vo.setDataSourceId(rs.getString("ID"));
				vo.setDbType(dbType);
				vo.setDbName(dbName);
				vo.setDbSchema(dbSchema);
				vo.setUsername(rs.getString("DB_USER"));
				vo.setPassword(rs.getString("DB_PWD"));
				String dbIp = rs.getString("DB_IP");
				String dbPort = rs.getString("DB_PORT");
				String unitUrl = DBUtil.getUrl(dbType, dbName, dbSchema, dbIp, dbPort);
				vo.setUrl(unitUrl);
				SCHEMA = dbSchema;
				logger.info("单位ID：" + unitId);
				logger.info("单位库：" + dbIp + "/" + dbName + "/" + dbSchema);
			}
		} catch (SQLException e) {
			logger.error("初始化单位数据库失败:" + e.getMessage());
		} finally {
			try {
				if (conn != null)
					conn.close();
				if (ps != null)
					ps.close();
				if (rs != null)
					rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return vo;
	}

	/**
	 * 数据库驱动
	 * @param dbType 数据库类型
	 * @return -
	 */
	public static String getDriverClass(String dbType) {
		String r = "";
		switch (dbType) {
			case "mysql":
				r = "com.mysql.cj.jdbc.Driver";
				break;
			case "oracle":
				r = "oracle.jdbc.OracleDriver";
				break;
			case "sqlserver":
				r = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
				break;
			case "postgresql":
				r = "org.postgresql.Driver";
				break;
			case "kingbase":
				r = "com.kingbase8.Driver";
				break;
		}
		return r;
	}

	/**
	 * URL
	 * @param dbType
	 * @param dbName
	 * @param dbSchema
	 * @param ip
	 * @param port
	 * @return
	 */
	public static String getUrl(String dbType, String dbName, String dbSchema, String ip, String port) {
		String r = "";
		switch (dbType) {
			case "mysql":
				r = "jdbc:mysql://" + ip + ":" + port + "/" + dbName + "?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
				break;
			case "oracle":
				r = "jdbc:oracle:thin:@//" + ip + ":" + port + "/" + dbName;
				break;
			case "sqlserver":
				r = "jdbc:sqlserver://" + ip + ":" + port + ";DatabaseName=" + dbName;
				break;
			case "postgresql":
				r = "jdbc:postgresql://" + ip + ":" + port + "/" + dbName;
				break;
			case "kingbase":
				r = "jdbc:kingbase8://" + ip + ":" + port + "/" + dbName + "?currentSchema=" + dbSchema + ",SYS_CATALOG";
				break;
		}
		return r;
	}
}
